package cn.ibobo.lease.app.controller;

import cn.ibobo.lease.app.service.UserBalanceService;
import cn.ibobo.lease.common.enums.ResultEnum;
import cn.ibobo.lease.common.util.Constant;
import cn.ibobo.lease.common.util.Md5Util;
import cn.ibobo.lease.common.util.ResultVOUtil;
import cn.ibobo.lease.common.util.UuidUtil;
import cn.ibobo.lease.common.vo.PayVO;
import cn.ibobo.lease.common.vo.ResultVO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.util.IOUtils;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.util.bcel.Const;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import weixin.popular.api.PayMchAPI;
import weixin.popular.bean.paymch.SandboxSignkey;
import weixin.popular.bean.paymch.Unifiedorder;
import weixin.popular.bean.paymch.UnifiedorderResult;
import weixin.popular.util.SignatureUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

import static cn.ibobo.lease.common.util.Constant.ALIPAY_PUBLIC_KEY;

/**
 * @Description 支付宝支付
 * @Author lililiang
 * @Date 2019/1/28 14:24
 * @Param
 * @Return
 */
@Api(tags = "阿里支付控制器")
@RestController
@RequestMapping("aliPay")
public class AliPayController {

    @Autowired
    private ResultVOUtil<Object> resultObject;
    @Autowired
    private UserBalanceService userBalanceService;

    private static final Log LOGGER = LogFactory.getLog(AliPayController.class);

    /**
     * @Description 唤起支付宝支付
     * @Author lililiang
     * @Date 2019/1/28 15:32
     * @Param [entity]
     * @Return cn.ibobo.lease.common.vo.ResultVO<java.lang.Object>
     */
    @ApiOperation(value = "唤起支付宝支付")
    @PostMapping("goPay")
    public ResultVO<Object> goPay(PayVO entity) {
        LOGGER.info("wPay/goPay entity = " + entity.toString());

        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(Constant.ALIPAY_GATE_WAY,
                Constant.ALIPAY_APP_ID, Constant.ALIPAY_APP_PRIVATE_KEY, "json",
                Constant.ALIPAY_CHARSET, Constant.ALIPAY_PUBLIC_KEY, "RSA2");
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("充值");//对一笔交易的具体描述信息。
        model.setSubject("骑享多");//商品的标题/交易标题/订单标题/订单关键字等。
//        model.setTotalAmount("0.01");//交易金额
        model.setTotalAmount(entity.getBalance().toString());//交易金额
        model.setTimeoutExpress(Constant.ALIPAY_TIMEOUT_EXPRESS);//订单超时时间 30m
        model.setProductCode("QUICK_MSECURITY_PAY");//商家和支付宝签约的产品码 QUICK_MSECURITY_PAY快捷支付
        //自定义回传参数
        String wxOrderId = UuidUtil.getUuid();
        Map map = new HashMap();
        map.put("uid", entity.getUid());
        map.put("wxOrderId", wxOrderId);
        map.put("balance", entity.getBalance());
        map.put("type", "ali");
        model.setPassbackParams(JSON.toJSONString(map));//支付回调的自定义参数
        model.setOutTradeNo(wxOrderId);//外部交易订单
        request.setBizModel(model);
        request.setNotifyUrl(Constant.ALIPAY_NOTIFY_URL + "aliPay/aliPayBack");//商户支付回调通知地址
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            //就是orderString 可以直接给客户端请求，无需再做处理。
            LOGGER.info("orderString :  "+response.getBody());
            return resultObject.success(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMsg(), response.getBody());
        } catch (AlipayApiException e) {
            LOGGER.info(e.getMessage());
            e.printStackTrace();
            return resultObject.error(ResultEnum.EXCEPTION.getCode(), ResultEnum.EXCEPTION.getMsg());
        }

    }

    /**
     * @Description 支付宝 回调通知
     * @Author lililiang
     * @Date 2019/4/2 18:59
     * @Param [request, response]
     * @Return java.lang.String
     */
    @PostMapping("aliPayBack")
    @ResponseBody
    public String aliPayBack(HttpServletRequest request, HttpServletResponse response) throws Exception {
        LOGGER.info("----------支付宝回调通知 start----------");
        String result;
        //获取支付宝POST过来反馈信息
        HashMap<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        System.out.println("================================params:" + params.toString());
        // 校验信息
        boolean flag = AlipaySignature.rsaCheckV1(params, Constant.ALIPAY_PUBLIC_KEY, Constant.ALIPAY_CHARSET,"RSA2");
        System.out.println("================================flag:" + flag);
        if(flag){
            //验签成功后 处理逻辑开始
            userBalanceService.balance(JSON.parseObject(params.get("passback_params"), HashMap.class));
            result = "success";
        }else{
            //验签失败
            result = "failure";
        }
        LOGGER.info("----------支付宝回调通知 end----------");
        return result;
    }


}
